package com.qipay.utils;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.qipay.baas.model.ChannelType;
import com.qipay.baas.model.Peizhi;
import com.qipay.channelType.ChannelTypeService;
import com.qipay.core.utils.SpringContextUtil;
import com.qipay.notice.NoticeService;
import io.jsonwebtoken.lang.Assert;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class GuavaCacheUtils {
    private static Cache<String, String> cache;
    private static Cache<String, List<ChannelType>> CacheChanel;
    private static Cache<String, Peizhi> peizhi;
    private final static String format = "%s_%s";
    private final int validCodeLength = 4;

    private Cache<String, Peizhi> getInstancePeizhi() {
        if (null == peizhi)
            peizhi = CacheBuilder.newBuilder().expireAfterWrite(24, TimeUnit.HOURS).build();
        return peizhi;
    }
    public void flushPeizhi() {
        // init
        NoticeService noticeService = (NoticeService) SpringContextUtil.getBean(NoticeService.class);
        Peizhi peizhi = noticeService.getPeizhi();
        getInstancePeizhi().put("peizhi", peizhi);
    }
    public Peizhi getPeizhi() {
        // init
            Peizhi peizhi = getInstancePeizhi().getIfPresent("peizhi");
        // generate
        if (peizhi==null) {
            NoticeService noticeService = (NoticeService) SpringContextUtil.getBean(NoticeService.class);
            peizhi = noticeService.getPeizhi();
            getInstancePeizhi().put("peizhi", peizhi);
        }
        return peizhi;
    }
    private Cache<String, List<ChannelType>> getInstanceChanel() {
        if (null == CacheChanel)
            CacheChanel = CacheBuilder.newBuilder().expireAfterWrite(60, TimeUnit.MINUTES).build();
        return CacheChanel;
    }
    public String generateChanelTypes(Byte orderChanelType) {
        String channelName = null;
        // init
        //获取储存的chanelTypes
        List<ChannelType> chanelTypes = getInstanceChanel().getIfPresent("chanelTypes");
        // generate
        if (chanelTypes==null) {
            //查询chanelTypes
            ChannelTypeService channelTypeService = (ChannelTypeService) SpringContextUtil.getBean(ChannelTypeService.class);
            chanelTypes = channelTypeService.selectAll();
            getInstanceChanel().put("chanelTypes", chanelTypes);
        }
        for(ChannelType channelType:chanelTypes){
            if(orderChanelType.equals(channelType.getId().byteValue())){
                channelName = channelType.getName();
                break;
            }
        }
        return channelName;
    }
    public List<ChannelType> getChanelTypes() {
        //获取储存的chanelTypes
        List<ChannelType> chanelTypes = getInstanceChanel().getIfPresent("chanelTypes");
        // generate
        if (chanelTypes==null) {
            //查询chanelTypes
            ChannelTypeService channelTypeService = (ChannelTypeService) SpringContextUtil.getBean(ChannelTypeService.class);
            chanelTypes = channelTypeService.selectAll();
            getInstanceChanel().put("chanelTypes", chanelTypes);
        }

        return chanelTypes;
    }
    private Cache<String, String> getInstance() {
        if (null == cache)
            cache = CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.MINUTES).build();
        return cache;
    }
    public String generateValidCode(String phone, String template) {

        // check
        Assert.isTrue(StringUtils.isNotBlank(phone));
        Assert.isTrue(StringUtils.isNotBlank(template));

        // init
        String key = String.format(format, phone, template);
        String validCode = getInstance().getIfPresent(key);

        // generate
        if (StringUtils.isBlank(validCode)) {
            validCode = RandomStringUtils.randomNumeric(validCodeLength);
            getInstance().put(key, validCode);
        }

        return validCode;
    }

    public String getValidCode(String phone, String template) {

        // check
        Assert.isTrue(StringUtils.isNotBlank(phone));
        Assert.isTrue(StringUtils.isNotBlank(template));

        // init
        String key = String.format(format, phone, template);
        return getInstance().getIfPresent(key);
    }
//    cache.invalidate();

    public void invalidateCode(String phone, String template){
        String key = String.format(format, phone, template);
        getInstance().invalidate(key);
    }
    public static void main(String[] args) throws InterruptedException {

        GuavaCacheUtils utils = new GuavaCacheUtils();
        utils.getInstance().put("1", "1");
        System.out.println(utils.getInstance().getIfPresent("1"));
        Thread.sleep(2 * 1000);
        System.out.println(utils.getInstance().getIfPresent("1"));

        utils = new GuavaCacheUtils();
        utils.getInstance().put("2", "2");
        System.out.println(utils.getInstance().getIfPresent("1"));
        System.out.println(utils.getInstance().getIfPresent("2"));
    }
}
